#include "unity.h"
#include "eth_FifoRecvData.h"
#include "mock_eth_commom.h"

// Declare the function under test (since it's not in a header)
extern u32 eth_FifoRecvData(XLlFifo *FifoPtr, EthernetFrame *FramePtr);

void setUp(void)
{
    // This is run before each test
}

void tearDown(void)
{
    // This is run after each test
}

void test_eth_FifoRecvData_WhenDataAvailableOnFirstCheck_ShouldReadAndReturnLength(void)
{
    // Arrange
    XLlFifo mockFifo;
    EthernetFrame mockFrame;
    u32 expectedLength = 1500;
    
    // Expectations
    XLlFifo_RxOccupancy_ExpectAndReturn(&mockFifo, 1);  // Data available
    XLlFifo_RxGetLen_ExpectAndReturn(&mockFifo, expectedLength);
    XLlFifo_Read_Expect(&mockFifo, &mockFrame, expectedLength);
    
    // Act
    u32 result = eth_FifoRecvData(&mockFifo, &mockFrame);
    
    // Assert
    TEST_ASSERT_EQUAL(expectedLength, result);
}

void test_eth_FifoRecvData_WhenNoDataAndTimeout_ShouldDecrementTimeoutAndReturnUndefined(void)
{
    // Arrange
    XLlFifo mockFifo;
    EthernetFrame mockFrame;
    u32 timeout = 100;
    u32 expectedLength = 0;
    
    // Expectations - No data available for all timeout iterations
    for(u32 i = 0; i < timeout; i++) {
        XLlFifo_RxOccupancy_ExpectAndReturn(&mockFifo, 0);  // No data
    }

    // Act
    u32 result = eth_FifoRecvData(&mockFifo, &mockFrame);
    
    // Assert
    TEST_ASSERT_EQUAL(expectedLength, result);
    // Note: FrameLength is undefined in this case as the loop exits without setting it
    // This is a potential issue in the original function
}

void test_eth_FifoRecvData_WhenDataAppearsAfterSeveralChecks_ShouldReadAndReturnLength(void)
{
    // Arrange
    XLlFifo mockFifo;
    EthernetFrame mockFrame;
    u32 expectedLength = 1024;
    u32 iterationsBeforeData = 10;
    
    // Expectations - No data for several iterations, then data available
    for(u32 i = 0; i < iterationsBeforeData; i++) {
        XLlFifo_RxOccupancy_ExpectAndReturn(&mockFifo, 0);  // No data
    }
    XLlFifo_RxOccupancy_ExpectAndReturn(&mockFifo, 1);  // Data finally available
    XLlFifo_RxGetLen_ExpectAndReturn(&mockFifo, expectedLength);
    XLlFifo_Read_Expect(&mockFifo, &mockFrame, expectedLength);
    
    // Act
    u32 result = eth_FifoRecvData(&mockFifo, &mockFrame);
    
    // Assert
    TEST_ASSERT_EQUAL(expectedLength, result);
}

